home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 5 / QRZ Ham Radio Callsign Database - Volume 5.iso / files / tcpip / amiga / asrc29p.lha / ppp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  21.5 KB  |  871 lines

  1. /*
  2.  *  PPP.C    -- Send and receive datagrams on serial lines with
  3.  *           Point-to-Point Protocol
  4.  *
  5.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  6.  *           UC Davis, Computing Services
  7.  *    PPP.08    05-90    [ks] include PPP protocol fields for VJ TCP compression
  8.  *    PPP.09    05-90    [ks] add UPAP negotiation and processing
  9.  *    PPP.10    07-90    [ks] make ppp open/close/reset work properly
  10.  *    PPP.14    08-90    [ks] change UPAP to PAP for consistency with RFC1172
  11.  *                 add RLSD link up/down signal handling
  12.  *                 add autobaud link speed message handling
  13.  *                 bit-shift constants must be explicitly long if shifted more than 8 bits
  14.  *                 must use unsigned char for comparison with SP_CHAR
  15.  *    PPP.15    09-90     [ks] update to KA9Q NOS v900828
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "global.h"
  20. #include "mbuf.h"
  21. #include "proc.h"
  22. #include "iface.h"
  23. #include "ax25.h"
  24. #include "slcompre.h"
  25. #include "ppp.h"
  26. #include "slip.h"
  27. #include "amiga/asy.h"
  28. #include "internet.h"
  29. #include "ip.h"
  30. #include "config.h"
  31. #include "trace.h"
  32.  
  33. /*#include "pktdrvr.h"*/
  34. /*#include "trace.h"*/
  35.  
  36. /* In pppcmd.c */
  37. extern int ppptrace;
  38.  
  39. /* Counter for PPP id field */
  40. unsigned char pppid;
  41.  
  42.  
  43. /* Routines local to this file */
  44. static struct mbuf *htonppp __ARGS((struct ppphdr *ppp, struct mbuf *data));
  45. /*static int pppq __ARGS((int16 dev,struct mbuf *data));*/
  46. static struct mbuf *ppp_decode __ARGS((int16 dev,unsigned char c));
  47. static struct mbuf *ppp_encode __ARGS((struct mbuf *bp, char flags,
  48.             int32 ctlmap));
  49.  
  50. /*
  51.  * FCS lookup table as generated by fcsgen.c
  52.  */
  53. static unsigned short fcstab[256] = {
  54.     0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 
  55.     0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 
  56.     0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 
  57.     0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 
  58.     0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 
  59.     0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 
  60.     0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 
  61.     0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 
  62.     0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 
  63.     0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 
  64.     0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 
  65.     0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 
  66.     0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 
  67.     0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 
  68.     0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 
  69.     0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 
  70.     0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 
  71.     0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 
  72.     0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 
  73.     0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 
  74.     0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 
  75.     0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 
  76.     0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 
  77.     0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 
  78.     0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 
  79.     0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 
  80.     0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 
  81.     0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 
  82.     0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 
  83.     0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 
  84.     0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 
  85.     0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  86. };
  87. #define pppfcs(fcs, c)        ((fcs >> 8) ^ fcstab[(fcs ^ c) & 0x00ff])
  88. #define SP_CHAR            0x20
  89.  
  90. /****************************************************************************/
  91.  
  92. /* Convert PPP header in host form to network form */
  93. static struct mbuf *
  94. htonppp(ppp, data)
  95. struct ppphdr *ppp;
  96. struct mbuf *data;
  97. {
  98.     struct mbuf *bp;
  99.     register unsigned char *cp;
  100.  
  101.     /* Prepend header onto packet data */
  102.     if ((bp = pushdown(data, PPP_HDRLEN)) == NULLBUF)
  103.     return NULLBUF;
  104.  
  105.     /* Load header with proper values */
  106.     cp = (unsigned char *)bp->data;
  107.     *cp++ = ppp->addr;
  108.     *cp++ = ppp->control;
  109.     (unsigned char *)put16(cp,ppp->type);
  110.  
  111.     return bp;
  112. }
  113.  
  114. /* Extract PPP header from incoming packet */
  115. int
  116. ntohppp(ppp, bpp)
  117. struct ppphdr *ppp;
  118. struct mbuf **bpp;
  119. {
  120. /*    ppp->addr = PULLCHAR(bpp);*/
  121.     pullup(bpp, &ppp->addr, 1);
  122. /*    ppp->control = PULLCHAR(bpp);*/
  123.     pullup(bpp, &ppp->control, 1);
  124.     ppp->type = pull16(bpp);
  125.     return(PPP_HDRLEN);
  126. }
  127.  
  128. /****************************************************************************/
  129.  
  130. /* Send IP datagram with Point-to-Point Protocol */
  131. int
  132. ppp_send(bp,iface,gateway,prec,del,tput,rel)
  133. struct mbuf *bp;    /* Buffer to send */
  134. struct iface *iface;    /* Pointer to interface control block */
  135. int32 gateway;        /* Ignored (PPP is point-to-point) */
  136. int prec;
  137. int del;
  138. int tput;
  139. int rel;
  140. {
  141.     int type = PPP_IP_TYPE;
  142.     register struct slip *sp;
  143.     register struct iphdr *iph;
  144.     register struct slcompress *scp;
  145.  
  146.     if(iface == NULLIF){
  147.         free_p(bp);
  148.         return -1;
  149.     }
  150.     sp = &Slip[iface->xdev];
  151.     if (sp->pppio->ipcpio.ipcp_state != IPCP_OPEN) {
  152.         free_p(bp);
  153.         sp->pppio->snderr++;
  154.         return -1;
  155.     }
  156.     if (sp->escaped & PPP_XMT_VJCOMPR) {
  157.         /* Look for TCP packets */
  158.         scp = sp->slcomp;
  159.         iph = (struct iphdr *)bp->data;
  160.         if (iph->ip_protocol == TCP_PTCL) {
  161.             /* Attempt IP/TCP header compression */
  162.             type = sl_compress_tcp(&bp, iph, scp, 1);
  163.             switch(type) {
  164.             case SL_TYPE_IP:
  165.                 type = PPP_IP_TYPE;
  166.                 break;
  167.             case SL_TYPE_COMPRESSED_TCP:
  168.                 type = PPP_COMPR_TYPE;
  169.                 break;
  170.             case SL_TYPE_UNCOMPRESSED_TCP:
  171.                 type = PPP_UNCOMP_TYPE;
  172.                 break;
  173.             default:
  174.                 return -1;
  175.             }
  176.         } else {
  177.             scp->sls_nontcp++;
  178.         }
  179.     }
  180.     sp->pppio->sndip++;
  181.     return (*iface->output)(iface,NULLCHAR,NULLCHAR,type,bp);
  182. }
  183. /* Send a packet with PPP header */
  184. int
  185. ppp_output(iface,dest,source,type,data)
  186. struct iface *iface;    /* Pointer to interface control block */
  187. char *dest;        /* Dest addr (ignored; PPP is point-to-point) */
  188. char *source;        /* Source addr (ignored; PPP is point-to-point) */
  189. int16 type;        /* PPP Protocol Type field */
  190. struct mbuf *data;    /* Actual data to be sent */
  191. {
  192.     struct slip *sp;
  193.     struct ppphdr ppp;
  194.     struct mbuf *bp;
  195.  
  196.     sp = &Slip[iface->xdev];
  197.     if (sp->pppio->state == PPP_CLOSED) {
  198.         free_p(data);
  199.         sp->pppio->snderr++;
  200.         return -1;
  201.     }
  202.     ppp.addr = HDLC_ALL_ADDR;
  203.     ppp.control = HDLC_UI;
  204.     ppp.type = type;
  205.     if ((bp = htonppp(&ppp, data)) == NULLBUF) {
  206.         free_p(data);
  207.         return -1;
  208.     }
  209.     return (*iface->raw)(iface,bp);
  210. }
  211. /* Encode a raw packet in PPP framing, put on link output queue, and kick
  212.  * transmitter
  213.  */
  214. int
  215. ppp_raw(iface,bp)
  216. struct iface *iface;
  217. struct mbuf *bp;
  218. {
  219.     register struct slip *sp;
  220.     struct mbuf *bp1;
  221.  
  222.     sp = &Slip[iface->xdev];
  223.     dump(iface,IF_TRACE_OUT,sp->type,bp);
  224.     /* Queue a frame on the PPP output queue and start transmitter */
  225.     if ((bp1 = ppp_encode(bp,sp->escaped,sp->pppio->ctlmap)) == NULLBUF)
  226.         return -1;    
  227.     if ((iface->trace != 0) && ((iface->trace & IF_TRACE_NOBC) == 0))
  228.         raw_dump(iface,IF_TRACE_OUT,bp1);
  229.     sp->pppio->sndpkt++;
  230.     return Slip[iface->xdev].send(iface->dev,bp1);
  231. }
  232.  
  233. /* Encode a packet in PPP format */
  234. static
  235. struct mbuf *
  236. ppp_encode(bp,flags,ctlmap)
  237. struct mbuf *bp;
  238. char flags;
  239. int32 ctlmap;
  240. {
  241.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  242.     register unsigned char *cp;
  243.     int c;
  244.     unsigned char abcd;
  245.     int16 calc_fcs;
  246.     struct ppphdr ppp;
  247.     int len = 1;
  248.     char compr_ac, compr_prot;
  249.  
  250.     /* Get the HDLC/PPP header */
  251.     ntohppp(&ppp, &bp);
  252.     /* Discard HDLC addr and control fields if possible */
  253.     compr_ac =  ((flags & PPP_XMT_ACCOMP)&&(ppp.type != PPP_LCP_TYPE));
  254.     /* Compress PPP protocol field if possible */
  255.     compr_prot = ((flags & PPP_XMT_PRCOMP) && 
  256.           (ppp.type < 0x100) &&
  257.           (ppp.type != PPP_LCP_TYPE));
  258.  
  259.     /* Calculate actual header length */
  260.     if (!compr_ac)
  261.         len += 2;
  262.     if (!compr_prot)
  263.         ++len;
  264.  
  265.     /* Prepend header onto packet data */
  266.     if ((bp = pushdown(bp, len)) == NULLBUF)
  267.         return NULLBUF;
  268.  
  269.     /* Load header with proper values */
  270.     cp = (unsigned char *)bp->data;
  271.     if (!compr_ac) {
  272. /*printf("B1 1 %x\n", (int)ppp.addr);*/
  273.         *cp++ = ppp.addr;
  274.         *cp++ = ppp.control;
  275.     }
  276.     if (!compr_prot)
  277.         *cp++ = (ppp.type >> 8);
  278.     *cp++ = (ppp.type & 0x00ff);
  279.  
  280.     /* Allocate output mbuf that's twice as long as the packet.
  281.      * This is a worst-case guess (consider a packet full of HDLC_FLAGs!)
  282.      */
  283.     lbp = alloc_mbuf((int16)(2*len_p(bp) + HDLC_ENVLEN));
  284.     if(lbp == NULLBUF){
  285.         /* No space; drop */
  286.         free_p(bp);
  287.         return NULLBUF;
  288.     }
  289.     cp = (unsigned char *)lbp->data;
  290.  
  291.     /* Flush out any line garbage */
  292.     *cp++ = HDLC_FLAG;
  293.  
  294.     /* Initialize FCS */
  295.     calc_fcs = HDLC_FCS_START;
  296.  
  297.  
  298. /*    while ((c = PULLCHAR(&bp)) != -1) {PULLCHARBUG*/
  299. /* attach asy serial.device 0 ppp pp 2048 576 2400
  300.  
  301.     /* Copy input to output, escaping special characters */
  302.  
  303.     while(pullup(&bp,&abcd,1) == 1) {
  304.         c=abcd;
  305.         /* Fold char value into FCS calculated so far */
  306.         calc_fcs = pppfcs(calc_fcs, c);
  307.         if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  308.             || (c == HDLC_ESC_ASYNC)
  309.             || (c == HDLC_FLAG)) {
  310. /*printf("B2 1\n");*/
  311.             *cp++ = HDLC_ESC_ASYNC;
  312.             *cp++ = (c ^ HDLC_ESC_COMPL);
  313.         } else {
  314. /*printf("B2 2\n");*/
  315.             *cp++ = c;
  316.         }
  317.     }
  318.  
  319.     /* Final FCS calculation */
  320.     calc_fcs ^= 0xffff;
  321.     c = (calc_fcs & 0x00ff);    /* Least significant byte first */
  322.     if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  323.          ||(c == HDLC_ESC_ASYNC)
  324.          ||(c == HDLC_FLAG)) {
  325.         *cp++ = HDLC_ESC_ASYNC;
  326.         *cp++ = (c ^ HDLC_ESC_COMPL);
  327.     } else {
  328.         *cp++ = c;
  329.     }
  330.     c = (calc_fcs >> 8);        /* Most significant byte next */
  331.     if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  332.          ||(c == HDLC_ESC_ASYNC)
  333.          ||(c == HDLC_FLAG)) {
  334.         *cp++ = HDLC_ESC_ASYNC;
  335.         *cp++ = (c ^ HDLC_ESC_COMPL);
  336.     } else {
  337.         *cp++ = c;
  338.     }
  339.  
  340.     /* Tye off the packet */
  341.     *cp++ = HDLC_FLAG;
  342.     lbp->cnt = cp - lbp->data;
  343.     return lbp;
  344. }
  345. /* Process incoming bytes in PPP format
  346.  * When a buffer is complete, return it; otherwise NULLBUF
  347.  */
  348. static
  349. struct mbuf *
  350. ppp_decode(dev,c)
  351. int16 dev;        /* PPP unit number */
  352. unsigned char c;    /* Incoming character */
  353. {
  354.     struct mbuf *bp;
  355.     register struct slip *sp;
  356.     register struct pppctl *pppiop;
  357.  
  358.     sp = &Slip[dev];
  359.     pppiop = Slip[dev].pppio;
  360.     switch(c){
  361.     case HDLC_FLAG:                /* Start/end of packet */
  362.         /* Wrap it up if end of a packet */
  363.         if (sp->rbp != NULLBUF) {
  364.             if (pppiop->calc_fcs == HDLC_FCS_FINAL) {
  365.                 /* Good packet, trim off FCS bytes */
  366.                 trim_mbuf(&sp->rbp, (len_p(sp->rbp)-2));
  367.             } else {
  368.                 /* FCS doesnt match; discard packet */
  369. /*putchar('\007');*/
  370.                 free_p(sp->rbp);
  371.                 sp->rbp = NULLBUF;
  372.                 sp->rcnt = 0;
  373.                 pppiop->csumerr++;
  374.             }
  375.         }
  376.         /* Prepare for next packet */
  377.         bp = sp->rbp;
  378.         sp->escaped &= ~PPP_BIT_BUCKET;
  379.         sp->escaped &= ~PPP_ESCAPED;
  380.         sp->rbp = NULLBUF;
  381.         sp->rcnt = 0;
  382.         pppiop->calc_fcs = HDLC_FCS_START;
  383.         return bp;    /* Will be NULLBUF if empty frame */
  384.  
  385.     case HDLC_ESC_ASYNC:            /* Async HDLC escape char */
  386.         sp->escaped |= PPP_ESCAPED;
  387.         return NULLBUF;
  388.     }
  389.  
  390.     if(sp->escaped & PPP_BIT_BUCKET)
  391.         /* Eat bytes til end of packet */
  392.         return NULLBUF;
  393.  
  394.     if(sp->escaped & PPP_ESCAPED){
  395.         /* Translate 2-char escape sequence back to original char */
  396.         sp->escaped &= ~PPP_ESCAPED;
  397.         c ^= HDLC_ESC_COMPL;
  398.     }
  399.     /* We reach here with a character for the buffer;
  400.      * make sure there's space for it
  401.      */
  402.     if(sp->rbp == NULLBUF){
  403.         /* Allocate first mbuf for new packet */
  404.         if((sp->rbp1 = sp->rbp = alloc_mbuf(PPP_ALLOC)) == NULLBUF)
  405.             return NULLBUF; /* No memory, drop */
  406.         sp->rcp = sp->rbp->data;
  407.     } else if(sp->rbp1->cnt == PPP_ALLOC){
  408.         /* Current mbuf is full; link in another */
  409.         if((sp->rbp1->next = alloc_mbuf(PPP_ALLOC)) == NULLBUF){
  410.             /* No memory, drop whole thing */
  411.             free_p(sp->rbp);
  412.             sp->rbp = NULLBUF;
  413.             sp->rcnt = 0;
  414.             return NULLBUF;
  415.         }
  416.         sp->rbp1 = sp->rbp1->next;
  417.         sp->rcp = sp->rbp1->data;
  418.     }
  419.     /* Store the character, increment fragment and total
  420.      * byte counts
  421.      */
  422.     /* HDLC address and control fields may be compressed out */
  423.     if ((sp->rcnt == 0)&&(c != HDLC_ALL_ADDR)) {
  424.         if (sp->escaped & PPP_RCV_ACCOMP) {
  425.             *sp->rcp++ = HDLC_ALL_ADDR;
  426.             *sp->rcp++ = HDLC_UI;
  427.             sp->rbp1->cnt += 2;
  428.             sp->rcnt += 2;
  429.         } else {
  430.             sp->escaped |= PPP_BIT_BUCKET;
  431.             free_p(sp->rbp);
  432.             sp->rbp = NULLBUF;
  433.             sp->rcnt = 0;
  434.             pppiop->rcverr++;
  435.  
  436. printf("rcverr: HDLC ALL ADDR compr not enabled\n");
  437. fflush(stdout);
  438.  
  439.             return NULLBUF;
  440.         }
  441.     }
  442.     /* HDLC control field must be present if not addr/ctl compression */
  443.     if ((sp->rcnt == 1)&&(c != HDLC_UI)) {
  444.         sp->escaped |= PPP_BIT_BUCKET;
  445.         free_p(sp->rbp);
  446.         sp->rbp = NULLBUF;
  447.         sp->rcnt = 0;
  448.         pppiop->rcverr++;
  449.  
  450. printf("rcverr: HDLC UI compr not enabled\n");
  451. fflush(stdout);
  452.  
  453.         return NULLBUF;
  454.     }
  455.     /* First byte of PPP protocol field may be compressed out */
  456.     if ((sp->rcnt == 2)&&((c & 1) == 1)) {
  457.         if (sp->escaped & PPP_RCV_PRCOMP) {
  458.             *sp->rcp++ = 0x00;
  459.             sp->rbp1->cnt++;
  460.             sp->rcnt++;
  461.         } else {
  462.             sp->escaped |= PPP_BIT_BUCKET;
  463.             free_p(sp->rbp);
  464.             sp->rbp = NULLBUF;
  465.             sp->rcnt = 0;
  466.             pppiop->rcverr++;
  467.  
  468. printf("rcverr: not PROT compr not enabled\n");
  469. fflush(stdout);
  470.  
  471.             return NULLBUF;
  472.         }
  473.     }
  474.     /* Second byte of PPP protocol field must be odd */
  475.     if ((sp->rcnt == 3)&&((c & 1) == 0)) {
  476.         sp->escaped |= PPP_BIT_BUCKET;
  477.         free_p(sp->rbp);
  478.         sp->rbp = NULLBUF;
  479.         sp->rcnt = 0;
  480.         pppiop->rcverr++;
  481.  
  482. printf("rcverr: second PPP protocol byte must be odd\n");
  483. fflush(stdout);
  484.  
  485.         return NULLBUF;
  486.     }
  487.  
  488.     /* Now add the actual character */
  489.     *sp->rcp++ = c;
  490.     sp->rbp1->cnt++;
  491.     sp->rcnt++;
  492.     pppiop->calc_fcs = pppfcs(pppiop->calc_fcs, c);
  493.     return NULLBUF;
  494. }
  495. /* Process PPP line input */
  496. void
  497. ppp_recv(dev,p1,p2)
  498. int dev;
  499. void *p1;
  500. void *p2;
  501. {
  502.     unsigned char c;
  503.     struct mbuf *bp,*nbp;
  504.     struct phdr *phdr;
  505.     struct slip *sp;
  506.  
  507.     sp = &Slip[dev];
  508.  
  509.     for(;;){
  510.         c = sp->get(sp->iface->dev);
  511.         if((bp = ppp_decode(dev,c)) == NULLBUF)
  512.  
  513.             continue;    /* More to come */
  514.  
  515.         if((nbp = pushdown(bp,sizeof(struct phdr))) == NULLBUF){
  516.             free_p(bp);
  517.             continue;
  518.         }
  519.         phdr = (struct phdr *)nbp->data;
  520.         phdr->iface = sp->iface;
  521.         phdr->type = sp->type;
  522.         enqueue(&Hopper,nbp);
  523.     }
  524. }
  525.  
  526. /****************************************************************************/
  527. #ifdef COMMENT
  528. /* Wait for autobaud message to set line speed then switch to regular PPP */
  529. void
  530. ppp_autobaud(dev,p1,p2)
  531. int dev;
  532. void *p1;
  533. void *p2;
  534. {
  535.     struct slip *sp;
  536.     struct iface *ifp;
  537.  
  538.     sp = &Slip[dev];
  539.     ifp = sp->iface;
  540.     /* Wait for an autobaud message */
  541.     asy_autobaud(ifp->dev);
  542.  
  543.     /* Ready for PPP packets */
  544.     ifp->proc = newproc("ppp recv", 256, ppp_recv, ifp->xdev, NULL, NULL);
  545.  
  546.     /* The LCP state machine has been waiting for us */
  547.     sp->pppio->state = PPP_CLOSED;
  548.     lcp_reset(sp->pppio);
  549.     lcp_start(sp);
  550.  
  551.     /* Terminate this process */
  552.     return;
  553. }
  554.  
  555. /* Keep track of RLSD signal; if RLSD is down, physical layer is down;
  556.  * if RLSD is asserted, physical layer is ready for traffic
  557.  */
  558. void
  559. ppp_rlsd(dev,p1,p2)
  560. int dev;
  561. void *p1;
  562. void *p2;
  563. {
  564.     int last_rlsd = 1;
  565.     int i;
  566.     unsigned long autospeed;
  567.     struct slip *sp;
  568.     struct pppctl *pppiop;
  569.     struct ipcpctl *ipcpiop;
  570.  
  571.     autospeed = (unsigned long)p1;
  572.     sp = &Slip[dev];
  573.     pppiop = sp->pppio;
  574.     for ( ; ; ) {
  575.         /* Wait for RLSD to change */
  576.         if (last_rlsd == 1) {
  577.             /* Down now, wait for RSLD to be asserted */
  578.             i = sp->get_rlsd(sp->iface->dev, 100);
  579.         } else {
  580.             /* Asserted now, wait for RSLD to be dropped */
  581.             i = sp->get_rlsd(sp->iface->dev, 1);
  582.         }
  583.  
  584.         last_rlsd = i;
  585. /*
  586. printf("ppp_rlsd: rlsd state change: %d\n",last_rlsd);
  587.  */
  588.         if (last_rlsd == 100) {
  589.             /* Physical layer now open for traffic */
  590.             if (ppptrace)
  591.                 mainlog(-1,"%s: PPP/RLSD: Physical layer ready",
  592.                     sp->iface->name);
  593.             /* RLSD signal is asserted */
  594.             if (pppiop->state == PPP_PL_DOWN) {
  595.                 if (autospeed == 0L) {
  596.                     pppiop->state = PPP_CLOSED;
  597.                     lcp_reset(pppiop);
  598.                     lcp_start(sp);
  599.                 } else {
  600.                     pppiop->state = PPP_AUTOBAUD;
  601.                 }
  602.             }
  603.         } else {
  604.             /* Physical layer is down */
  605.             if (ppptrace)
  606.                 mainlog(-1,"%s: PPP/RLSD: Physical layer down",
  607.                     sp->iface->name);
  608.             /* RLSD signal not asserted */
  609.             if ((pppiop->state != PPP_CLOSED) &&
  610.                 (pppiop->state != PPP_AUTOBAUD)) {
  611.                 ipcpiop = &(pppiop->ipcpio);
  612.                 if (ipcpiop->ipcp_state == IPCP_OPEN) {
  613.                     /* Remove routing entry from table */
  614.                     rt_drop(ipcpiop->attempt_dest,
  615.                         (unsigned int)32);
  616.                 }
  617.                 /* Blast any layers that are open */
  618.                 ipcp_reset(sp);
  619.                 pap_init(sp);
  620.                 lcp_reset(pppiop);
  621.             }
  622.             /* Physical layer closed to all traffic */
  623.             pppiop->state = PPP_PL_DOWN;
  624.             if (autospeed != 0L) {
  625.                 killproc(sp->iface->proc);
  626.                 sp->iface->proc = NULLPROC;
  627.                 sp->iface->proc = newproc("ppp autobaud", 256,
  628.                               ppp_autobaud, sp->iface->xdev, NULL, NULL);
  629.             }
  630.         }
  631.     }
  632. }
  633. #endif
  634.  
  635. /****************************************************************************/
  636.  
  637. /* Initialize PPP control structures for a Point-to-Point interface */
  638. int
  639. ppp_init(dev)
  640. int dev;
  641. {
  642.     struct slip *sp;
  643.     struct pppctl *pppiop;
  644.  
  645.     sp = &Slip[dev];
  646.     pppiop = sp->pppio;
  647.  
  648.     pppiop->state = PPP_CLOSED;    /* Ready for traffic */
  649.     pppiop->ctlmap = DEF_CTL_MAP;    /* Overall PPP parameters */
  650.  
  651.     lcp_init(sp);            /* Link Control parameters */
  652.     pap_init(sp);            /* Peer Authentication parameters */
  653.     ipcp_init(sp);            /* IP Control parameters */
  654.  
  655.     return 0;
  656. }
  657.  
  658. /* Close the PPP interface */
  659. int
  660. ppp_close(sp,pl_too)
  661. struct slip *sp;
  662. int pl_too;
  663. {
  664.     int argc = 2;
  665.     char *argv[] = {
  666.         "dtr",
  667.         "0",
  668.     };
  669.  
  670.     ipcp_close(sp);            /* Close IP layer */
  671.     lcp_close(sp);            /* Close Link layer */
  672.     if (pl_too) {            /* Close physical layer */
  673.         sp->iface->ioctl(sp->iface,argc,argv);
  674.     }
  675.     sp->pppio->lcpio.active = -1;    /* We are strictly closed */
  676.     tprintf("PPP interface  %s  closed\n",sp->iface->name);
  677.     return 0;
  678. }
  679.  
  680.  
  681. /* Process incoming PPP packets */
  682. void
  683. pproc(iface,bp)
  684. struct iface *iface;
  685. struct mbuf *bp;
  686. {
  687.     struct ppphdr hdr;
  688.     struct pppctl *pppiop;
  689.     register struct iphdr *iph;
  690.     struct slip *sp;
  691.     register int16 len;
  692.  
  693.  
  694.     sp = &Slip[iface->xdev];
  695.     pppiop = Slip[iface->xdev].pppio;
  696.     pppiop->rcvpkt++;
  697.     /* Remove PPP header and kick packet upstairs */
  698.     ntohppp(&hdr, &bp);
  699.     switch(hdr.type) {
  700.     case PPP_IP_TYPE:    /* Regular IP */
  701.         if ((pppiop->ipcpio.ipcp_state != IPCP_OPEN) &&
  702.             (pppiop->ipcpio.ipcp_state != IPCP_TERMINATE)) {
  703.             if (ppptrace)
  704.                 mainlog(-1,"PPP link not open for IP traffic; dropping IP packet");
  705.             pppiop->rcverr++;
  706.  
  707. printf("rcverr: link not open for IP\n");
  708. fflush(stdout);
  709.  
  710.             free_p(bp);
  711.             break;
  712.         }
  713.         pppiop->rcvip++;
  714.         if (sp->escaped & PPP_RCV_VJCOMPR) {
  715.             iph = (struct iphdr *)bp->data;
  716.             if (iph->ip_protocol == TCP_PTCL)
  717.                 sp->slcomp->sls_tcpin++;
  718.             else
  719.                 sp->slcomp->sls_nontcpin++;
  720.         }
  721.         ip_route(iface,bp,0);
  722.         break;
  723.     case PPP_COMPR_TYPE:    /* Van Jacobson Compressed TCP/IP */
  724.         if (pppiop->ipcpio.ipcp_state != IPCP_OPEN) {
  725.             if (ppptrace)
  726.                 mainlog(-1,"PPP link not open for IP traffic; dropping Compressed TCP/IP packet");
  727.             pppiop->rcverr++;
  728.  
  729. printf("rcverr: link not open for VJ Compr\n");
  730. fflush(stdout);
  731.  
  732.             free_p(bp);
  733.             break;
  734.         }
  735.         if ((len = len_p(bp)) < 3) {
  736.             if (ppptrace)
  737.                 mainlog(-1,"VJ Compressed TCP/IP packet error: short");
  738.             free_p(bp);
  739.             pppiop->rcverr++;
  740.  
  741. printf("rcverr: short VJ Compr pkt\n");
  742. fflush(stdout);
  743.  
  744.             break;
  745.         }
  746.         /* Got a packet at least minimum length of
  747.          * a compressed packet
  748.          */
  749.         if ((sp->escaped & PPP_RCV_VJCOMPR) == 0) {
  750.             if (ppptrace)
  751.                 mainlog(-1,"VJ Compressed TCP/IP packet error: not enabled");
  752.             pppiop->rcverr++;
  753. printf("rcverr: VJ Compr not enabled\n");
  754. fflush(stdout);
  755.  
  756.             free_p(bp);
  757.             break;
  758.         }
  759.         /* Got a packet other than regular IP */
  760.         len = sl_uncompress_tcp(&bp, len,
  761.             SL_TYPE_COMPRESSED_TCP,
  762.             sp->slcomp);
  763.         if (len <= 0) {
  764.             free_p(bp);
  765.             bp = NULLBUF;
  766.             pppiop->rcverr++;
  767. printf("rcverr: VJ Compr decompr error\n");
  768. fflush(stdout);
  769.  
  770.             break;
  771.         }
  772.         pppiop->rcvip++;
  773.         ip_route(iface,bp,0);
  774.         break;
  775.     case PPP_UNCOMP_TYPE:    /* Van Jacobson Uncompressed TCP/IP */
  776.         if (pppiop->ipcpio.ipcp_state != IPCP_OPEN) {
  777.             if (ppptrace)
  778.                 mainlog(-1,"PPP link not open for IP traffic; dropping Uncompressed TCP/IP packet");
  779.             free_p(bp);
  780.             pppiop->rcverr++;
  781. printf("rcverr: link not open for VJ uncompr\n");
  782. fflush(stdout);
  783.  
  784.             break;
  785.         }
  786.         if ((len = len_p(bp)) < 3) {
  787.             if (ppptrace)
  788.                 mainlog(-1,"VJ Uncompressed TCP/IP packet error: short");
  789.             free_p(bp);
  790.             pppiop->rcverr++;
  791.  
  792. printf("rcverr: short VJ Uncompr pkt\n");
  793. fflush(stdout);
  794.  
  795.             break;
  796.         }
  797.         /* Got a packet at least minimum length of
  798.          * a compressed packet
  799.          */
  800.         if ((sp->escaped & PPP_RCV_VJCOMPR) == 0) {
  801.             if (ppptrace)
  802.                 mainlog(-1,"VJ Uncompressed TCP/IP packet error: not enabled");
  803.             free_p(bp);
  804.             pppiop->rcverr++;
  805.  
  806. printf("rcverr: VJ Uncompr not enabled\n");
  807. fflush(stdout);
  808.  
  809.             break;
  810.         }
  811.         /* Got a packet other than regular IP */
  812.         len = sl_uncompress_tcp(&bp, len,
  813.             SL_TYPE_UNCOMPRESSED_TCP,
  814.             sp->slcomp);
  815.         if (len <= 0) {
  816.             free_p(bp);
  817.             bp = NULLBUF;
  818.             pppiop->rcverr++;
  819.  
  820. printf("rcverr: VJ Uncompr decompr error\n");
  821. fflush(stdout);
  822.  
  823.             break;
  824.         }
  825.         pppiop->rcvip++;
  826.         ip_route(iface,bp,0);
  827.         break;
  828.     case PPP_LCP_TYPE:    /* Link Control Protocol */
  829.         pppiop->rcvlcp++;
  830.         lcpproc(iface,bp);
  831.         break;
  832.     case PPP_PAP_TYPE:    /* Password Authenticate Protocol */
  833.         if (pppiop->lcpio.lcp_state != LCP_OPEN) {
  834.             if (ppptrace)
  835.                 mainlog(-1,"not in PAP phase; dropping PAP packet");
  836.             free_p(bp);
  837.             pppiop->rcverr++;
  838.  
  839. printf("rcverr: not open for PAP\n");
  840. fflush(stdout);
  841.  
  842.             break;
  843.         }
  844.         pppiop->rcvpap++;
  845.         papproc(iface,bp);
  846.         break;
  847.     case PPP_IPCP_TYPE:    /* IP Control Protocol */
  848.         if (pppiop->lcpio.lcp_state != LCP_OPEN) {
  849.             if (ppptrace)
  850.                 mainlog(-1,"IPCP closed; dropping IPCP packet");
  851.             free_p(bp);
  852.             pppiop->rcverr++;
  853.  
  854. printf("rcverr: not open for IPCP\n");
  855. fflush(stdout);
  856.  
  857.             break;
  858.         }
  859.         pppiop->rcvipcp++;
  860.         ipcpproc(iface,bp);
  861.         break;
  862.     default:
  863.         if (ppptrace)
  864.             mainlog(-1,"Unknown PPP packet type: %x; dropping packet",hdr.type);
  865.         free_p(bp);
  866.         pppiop->rcvunk++;
  867.         break;
  868.     }
  869.     return;
  870. }
  871.